package com.htthorizon.gateway.filter;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import com.htthorizon.common.core.constant.CacheConstants;
import com.htthorizon.common.core.constant.SecurityConstants;
import com.htthorizon.common.core.context.SecurityContextHolder;
import com.htthorizon.common.core.utils.JwtUtils;
import com.htthorizon.common.core.utils.ServletUtils;
import com.htthorizon.common.core.utils.StringUtils;
import com.htthorizon.common.core.utils.ip.IpUtils;
import com.htthorizon.common.redis.service.RedisService;
import com.htthorizon.system.api.RemoteLogService;
import com.htthorizon.system.api.domain.SysLogininfor;
import com.htthorizon.system.api.domain.SysOperLog;
import com.htthorizon.system.api.exception.KeyNotException;
import com.htthorizon.system.api.exception.MaxUserException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.util.Collection;
import java.util.List;

/**
 * @author Brilliant
 */
@Component
@Slf4j
public class UnauthorizedFilter implements GlobalFilter, Ordered {

    @Autowired
    private RedisService redisService;
//
//    @Autowired
//    private RemoteLogService logService;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        ServerHttpRequest.Builder mutate = request.mutate();
        String userName = SecurityContextHolder.getUserName();
        String url1 = request.getURI().getPath();
        String ipAddr1 = IpUtils.getIpAddr1(request);

        log.info("请求ip:【"+ipAddr1+"】");
        if (url1.contains("login")) {

            log.info("验证最大会话数是否满足要求");
            Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
            Object cacheObject = redisService.getCacheObject(CacheConstants.MAX_SESSION_NUM_KEY);
            if (cacheObject == null) {
                redisService.setCacheObject(CacheConstants.MAX_SESSION_NUM_KEY,1000);
            }
            Integer maxSessions = redisService.getCacheObject(CacheConstants.MAX_SESSION_NUM_KEY);
            log.info("最大会话数:【{}】",maxSessions);
            log.info("keys:【{}】",keys.size());
            if (keys.size() >= maxSessions){
                HttpHeaders headers1 = request.getHeaders();
                System.out.println("请求头【"+headers1+"】");
                List<String> list1 = headers1.get("authorization");
                String userName1;
                if (list1!=null&&!(list1.isEmpty())){
                    String token = list1.get(0);
                    userName1 = JwtUtils.getUserName(token);
                } else {
                    userName1 = SecurityContextHolder.getUserName();
                }
                SysOperLog sysLogininfor = SysOperLog.build(userName1, IpUtils.getIpAddr1( exchange.getRequest()), "已达最大会话数",request.getMethod().toString(),url1,request);
                redisService.setCacheObject("log:"+sysLogininfor.getCreateTime(),sysLogininfor);

                throw new MaxUserException();
            }
        }
        return chain.filter(exchange.mutate().request(mutate.build()).build());
    }

    @Override
    public int getOrder() {
        return -10000;
    }
}
